import { Subject } from 'rxjs';
import {
  UserState,
  ChannelType,
  DeviceState,
  ContactState,
  DirectionType,
  DeviceErrorType,
  ContactErrorType,
  CommlibErrorType,
  CommlibEventType,
  DeviceEventType,
  ContactEventType,
  MessageFormat,
  MessageType,
  ProviderType
} from '../common/commlib.enums';

export interface IChatMsgPayload {
  message: IMessage;
  typing: boolean;
  left: any;
  join: any;
}

export interface ICommunicationLibrary {
  onNewEvent$: Subject<any>;
  onError$: Subject<any>;

  getDevices(): IDevice[];
  getDeviceById(id: string): IDevice;
  getDeviceByType(channelType: ChannelType): IDevice;
  getUserState(): UserState;
  setUserState(newState: UserState): void;
}

export interface IContact {
  onNewEvent$: Subject<IEvent>;
  onError$: Subject<IError>;

  getId(): string;
  getFromAddress(): any;

  getState(): ContactState;
  getDevice(): IDevice;

  getCreatedAt(): Date;
  getCreatedBy(): any;

  getEndedAt(): Date;
  getEndedBy(): any;

  getConnectedAt(): Date;
  getQueueName(): any;

  getDirection(): DirectionType;

  accept(): any;
  decline(): any;
  hold(): any;
  unHold(): any;
  mute(): any;
  unMute(): any;
  hangup(): any;

  getUsers(): any[];
  getPreviousMessages(parameters: any): any;

  sendMessage(messageParams: IMessageParams): any;
  typing(parameters?: any): any;
}

export interface IContactDataModel {
  id: string;
  name: string;
  state: string;
  createdBy: string;
  createdAt: number;
}

export interface IDevice {
  onNewEvent$: Subject<IEvent>;
  onError$: Subject<IError>;

  getId(): string;
  getState(): DeviceState;
  getStatus(): string;
  getContacts(): IContact[];
  getType(): ChannelType;
  getAddress(): any;
  getName(): string;
  getAdditionalData(): IAdditionalData;

  register(parameters?: any): void;
  unregister(): void;
  setState(state: DeviceState): void;
  createContact(parameters?: any): Promise<IContact>;
  joinContact(contactId: string): Promise<IContact>;
}

export interface IError {
  type: DeviceErrorType | ContactErrorType | CommlibErrorType;
  message: string;
  payload: any;
}

export interface IEvent {
  eventType: CommlibEventType | DeviceEventType | ContactEventType;
  payload:
    | IContact
    | IDevice
    | IMessage
    | ISender
    | IMessage[]
    | boolean
    | string;
}
export interface IMessageParams {
  messageContent: string;
  data: string;
  msgCustomType: string;
}

export interface IMessage {
  id: string;
  contactId: string;
  index: number;
  content: any;
  createdAt: Date;
  updatedAt: Date;
  sender: string | ISender;
  format?: MessageFormat;
  type: MessageType;
  additionalProperties?: any;
}
export interface ISender {
  userId: string;
  nickname: string;
  profileUrl: string;
  isActive: boolean;
}

export interface IScript {
  name?: string;
  url: string;
}

export interface IAdditionalData {
  getUnassignContacts(): Promise<IContactDataModel[]>;
  deleteMessage(contactId: string, messageId: string): any;
}

export interface IDeviceConfiguration {
  id: string;
  key: string;
  name: string;
  type: ProviderType;
  isActive: boolean;
  location: IDeviceLocation;
  channels: ChannelType[];
  parameters: any;
}

export interface IDeviceLocation {
  path: string;
  className: string;
}
